home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / rwvector.lha / RWVector2.1 / src / xvec.cc < prev    next >
C/C++ Source or Header  |  1989-08-18  |  5KB  |  246 lines

  1. /*
  2.  *    Definitions for <T>Vec
  3.  *
  4.  *    Copyright (C) 1988, 1989.
  5.  *
  6.  *    Dr. Thomas Keffer
  7.  *    Rogue Wave Associates
  8.  *    P.O. Box 85341
  9.  *    Seattle WA 98145-1341
  10.  *
  11.  *    Permission to use, copy, modify, and distribute this
  12.  *    software and its documentation for any purpose and
  13.  *    without fee is hereby granted, provided that the
  14.  *    above copyright notice appear in all copies and that
  15.  *    both that copyright notice and this permission notice
  16.  *    appear in supporting documentation.
  17.  *    
  18.  *    This software is provided "as is" without any
  19.  *    expressed or implied warranty.
  20.  *
  21.  *
  22.  *    @(#)xvec.cc    2.1    8/18/89
  23.  */
  24.  
  25. #define NO_VECTOR_MATHFUN
  26. #include "rw/<T>Vec.h"
  27. #define TYPE <T>_TYPE
  28. #include "vecdefs.h"
  29.  
  30. #if TYPE==DComplex_TYPE
  31. #include "rw/<P>Vec.h"
  32. #endif
  33.  
  34. #if NEEDS_OVERLOAD
  35. overload <T>Copy;
  36. #endif
  37.  
  38. inline void
  39. <T>Copy(register const <T>* src, register <T>* dst, register int n)
  40. // Copy n <T> elements from src to dst with stride of 1
  41. {
  42.   while (n--) *dst++ = *src++;
  43. }
  44.  
  45. inline void
  46. <T>Copy(register const <T>* src, register int str,
  47.     register <T>* dst, register int n)
  48. // Copy n <T> elements from src to dst with stride str
  49. {
  50.   while (n--){
  51.     *dst++ = *src; src += str;
  52.   }
  53. }
  54.  
  55. inline void
  56. <T>Copy(register const <T>* src, register int srcstr,
  57.     register <T>* dst, register int dststr, register int n)
  58. {
  59.   while (n--){
  60.     *dst = *src; src += srcstr; dst += dststr;
  61.   }
  62. }
  63.  
  64. <T>Vec::<T>Vec()
  65. {
  66.   block = new <T>Block(0);
  67.   npts = 0;
  68.   step = 1;
  69.   begin = block->data();
  70. }
  71.  
  72. <T>Vec::<T>Vec(unsigned n)
  73. {
  74.   block = new <T>Block(n);
  75.   npts = n;
  76.   step = 1;
  77.   begin = block->data();
  78. }
  79.  
  80. <T>Vec::<T>Vec(unsigned n, <T> val)
  81. {
  82.   block = new <T>Block(n, val);
  83.   npts = n;
  84.   step = 1;
  85.   begin = block->data();
  86. }
  87.  
  88. <T>Vec::<T>Vec(unsigned n, <T> val, <T> by)
  89. {
  90.   block = new <T>Block(n, val, by);
  91.   npts = n;
  92.   step = 1;
  93.   begin = block->data();
  94. }
  95.  
  96. #if TYPE==DComplex_TYPE || TYPE==FComplex_TYPE
  97. <T>Vec::<T>Vec(const <P>Vec& re)
  98. {
  99.   register int nn = npts = re.length();
  100.   block = new <T>Block(nn);
  101.   step = 1;
  102.   register <T>* cp = begin = block->data();
  103.   register <P>* rp = re.data();
  104.   register int rstride = re.stride();
  105.   while(nn--){ *cp++ = <T>(*rp); rp += rstride; }
  106. }  
  107.  
  108. <T>Vec::<T>Vec(const <P>Vec& re, const <P>Vec& im)
  109. {
  110.   register int nn = npts = re.length();
  111.   lengthCheck(im.length());
  112.   block = new <T>Block(nn);
  113.   step = 1;
  114.   register <T>* cp = begin = block->data();
  115.   register <P>* rp = re.data();
  116.   register <P>* ip = im.data();
  117.   register int rstride = re.stride();
  118.   register int istride = im.stride();
  119.   while(nn--){
  120.     *cp++ = <T>(*rp, *ip);
  121.     rp += rstride;
  122.     ip += istride;
  123.   }
  124. }
  125.  
  126. #endif
  127.  
  128. <T>Vec::<T>Vec(const <T>Vec& a)
  129. {
  130.   block = a.block;
  131.   block->add_reference();
  132.   npts = a.npts;
  133.   begin = a.begin;
  134.   step = a.step;
  135. }
  136.  
  137. <T>Vec::<T>Vec(const <T>* dat, unsigned n)
  138. {
  139.   npts = n;
  140.   block = new <T>Block(n);
  141.   step = 1;
  142.   <T>Copy(dat, begin = block->data(), n);
  143. }
  144.  
  145. <T>Vec::<T>Vec(<T>Vec& v, int start, unsigned n, int str)
  146. {
  147.   int maxv = v.length()-1;    // Last subscript in v
  148.   int maxslice = start + (n-1)*str; // Last subscript in slice
  149.   if(start<0 || start>maxv || maxslice<0 || maxslice>maxv)
  150.     sliceErr(v.length(), start, n, str);
  151.  
  152.   block = v.block;
  153.   block->add_reference();
  154.   begin = v.begin + start*v.step;
  155.   npts = n;
  156.   step = str*v.step;
  157. }
  158.  
  159. <T>Vec::~<T>Vec()
  160. {
  161.   delete block;
  162. }
  163.  
  164. <T>Vec
  165. <T>Vec::slice(int start, unsigned n, int str)
  166. {
  167.   <T>Vec temp(*this, start, n, str);
  168.   return temp;
  169. }
  170.  
  171. <T>Vec&
  172. <T>Vec::operator=(const <T>Vec& a)
  173. {
  174.   lengthCheck(a.length());
  175.   <T>Copy(a.begin, a.step, begin, step, npts);
  176.   return *this;
  177. }
  178.  
  179.  
  180. <T>Vec&
  181. <T>Vec::operator=(<T> d)
  182. {
  183.   register int n = length();
  184.   register <T>* tp = data();
  185.   register int tj = stride();
  186.   REGISTER <T> dd = d;
  187.   while(n--){
  188.     *tp = dd; tp += tj;
  189.   }
  190.   return *this;
  191. }
  192.  
  193. <T>Vec&
  194. <T>Vec::reference(<T>Vec& v)
  195. {
  196.   delete block;            // Detach from old block
  197.   block = v.block;        // Attach new block
  198.   block->add_reference();
  199.   npts = v.npts;
  200.   step = v.step;
  201.   begin = v.begin;
  202.   return *this;
  203. }
  204.  
  205. // Return copy of self with distinct instance variables
  206. <T>Vec
  207. <T>Vec::deepCopy()
  208. {
  209.   <T>Vec temp(npts);
  210.   <T>Copy(begin, step, temp.data(), npts);
  211.   return temp;
  212. }
  213.  
  214. // Guarantee that references==1 and stride==1
  215. void
  216. <T>Vec::deepenShallowCopy()
  217. {
  218.   if(block->references() > 1 || stride() != 1 || begin != block->data() ){
  219.     <T>Block* newblock = new <T>Block(npts);
  220.     <T>Copy(begin, step, newblock->data(), npts);
  221.     delete block;        // Detach old block
  222.     block = newblock;
  223.     step = 1;
  224.     begin = block->data();
  225.   }
  226. }
  227.  
  228. void
  229. <T>Vec::resize(unsigned N)
  230. {
  231.   if(N != npts){
  232.     <T>Block* newblock = new <T>Block(N);
  233.     // Copy over old stuff.
  234.     int newLength = min( int(npts), int(N) );
  235.     <T>Copy(begin, step, newblock->data(), newLength );
  236.     delete block;        // Disconnect from old block
  237.     block = newblock;
  238.     step = 1;
  239.     begin = block->data();
  240.     // If vector has grown, zero out the extra storage
  241.     unsigned hold = npts;
  242.     npts = N;
  243.     if(hold<N)slice(hold, N-hold, 1) = <T>(0);
  244.   }
  245. }
  246.